package com.lzc.tlmail.tlmailware.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lzc.common.to.LockStockTastTO;
import com.lzc.common.to.SkuWareVo;
import com.lzc.common.to.StockTaskDetailto;
import com.lzc.common.to.mq.Orderto;
import com.lzc.common.utils.R;
import com.lzc.tlmail.tlmailware.Vo.LockWareOrdervo;
import com.lzc.tlmail.tlmailware.Vo.OrderCartSkuvo;
import com.lzc.common.exception.NoSuchWareException;
import com.lzc.tlmail.tlmailware.Vo.Ordervo;
import com.lzc.tlmail.tlmailware.entity.WareOrderTaskDetailEntity;
import com.lzc.tlmail.tlmailware.entity.WareOrderTaskEntity;
import com.lzc.tlmail.tlmailware.feign.OrderFeignService;
import com.lzc.tlmail.tlmailware.service.WareOrderTaskDetailService;
import com.lzc.tlmail.tlmailware.service.WareOrderTaskService;
import lombok.Data;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzc.common.utils.PageUtils;
import com.lzc.common.utils.Query;

import com.lzc.tlmail.tlmailware.dao.WareSkuDao;
import com.lzc.tlmail.tlmailware.entity.WareSkuEntity;
import com.lzc.tlmail.tlmailware.service.WareSkuService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {

    @Autowired
    private WareOrderTaskService wareOrderTaskService;
    @Autowired
    private WareOrderTaskDetailService wareOrderTaskDetailService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private OrderFeignService orderFeignService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                new QueryWrapper<WareSkuEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 查询仓库的sku商品
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<WareSkuEntity> wareSkuEntityQueryWrapper = new QueryWrapper<>();
        String skuId = (String) params.get("skuId");
        if(!StringUtils.isEmpty(skuId)){
            wareSkuEntityQueryWrapper.eq("sku_id",skuId);
        }

        String wareId = (String) params.get("wareId");
        if(!StringUtils.isEmpty(wareId)){
            wareSkuEntityQueryWrapper.eq("ware_id",wareId);
        }
        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                wareSkuEntityQueryWrapper
        );

        return new PageUtils(page);
    }

    /**
     * 根据sku查询是否有库存
     * @param skuIds
     * @return
     */
    @Override
    public List<SkuWareVo> getSkusHasStock(List<Long> skuIds) {
        List<SkuWareVo> skuWareVos = skuIds.stream().map(skuid -> {
            SkuWareVo skuWareVo = new SkuWareVo();
            skuWareVo.setSkuId(skuid);
            //得到库存
            Long count = baseMapper.getStock(skuid);
            skuWareVo.setHasStock(count==null?false:count > 0);
            return skuWareVo;
        }).collect(Collectors.toList());
        return skuWareVos;
    }

    /**
     * 锁定库存
     * @param lockWareOrdervo
     * @return
     */
    @Transactional
    @Override
    public Boolean lockWareOrder(LockWareOrdervo lockWareOrdervo) {
        WareOrderTaskEntity wareOrderTaskEntity = new WareOrderTaskEntity();
        wareOrderTaskEntity.setCreateTime(new Date());
        wareOrderTaskEntity.setOrderSn(lockWareOrdervo.getOrdersn());
        //添加工作单
        wareOrderTaskService.save(wareOrderTaskEntity);
        //先查出所有sku有库存的仓库 没有库存直接抛异常回滚
        List<OrderCartSkuvo> orderCartSkuvos = lockWareOrdervo.getOrderCartSkuvos();
        List<HasStockSkuWare> collect = orderCartSkuvos.stream().map(item -> {
            HasStockSkuWare hasStockSkuWare = new HasStockSkuWare();
            hasStockSkuWare.setSkuId(item.getSkuId());
            hasStockSkuWare.setNum(item.getCount());
            List<Long> wareIds = this.getBaseMapper().checkWareBySkuId(item.getSkuId());
            hasStockSkuWare.setWareIds(wareIds);
            return hasStockSkuWare;
        }).collect(Collectors.toList());

        //查出来之后就把购买的数量放进去 能放进去就可以 不能放就库存不足也抛异常
        //锁定库存
        for (HasStockSkuWare stockSkuWare : collect) {
            Boolean isStock=false;
            Long skuId = stockSkuWare.getSkuId();
            Integer num = stockSkuWare.getNum();
            List<Long> wareIds = stockSkuWare.getWareIds();
            if(wareIds==null&&wareIds.size()==0){
                throw new NoSuchWareException(skuId);
            }
            for (Long wareId : wareIds) {
               Long result=this.getBaseMapper().lockSkuStock(skuId,wareId,num);
               if(result==1){
                   isStock=true;
                   //走到这里说明库存锁定成功
                   WareOrderTaskDetailEntity taskDetailEntity = new WareOrderTaskDetailEntity();
                   taskDetailEntity.setSkuId(skuId);
                   taskDetailEntity.setSkuNum(num);
                   taskDetailEntity.setTaskId(wareOrderTaskEntity.getId());
                   taskDetailEntity.setWareId(wareId);
                   taskDetailEntity.setLockStatus(1);
                   wareOrderTaskDetailService.save(taskDetailEntity);
                   LockStockTastTO lockStockTastTO = new LockStockTastTO();
                   lockStockTastTO.setTaskId(wareOrderTaskEntity.getId());
                   StockTaskDetailto stockTaskDetailto = new StockTaskDetailto();
                   BeanUtils.copyProperties(taskDetailEntity,stockTaskDetailto);
                   lockStockTastTO.setStockTaskDetailto(stockTaskDetailto);
                   //发送消息
                   rabbitTemplate.convertAndSend("stock-event-exchange","stock.locked",lockStockTastTO);
                   break;
               }else {
                   //重试下一次锁定
               }
            }
            if(isStock==false){
               throw new NoSuchWareException(skuId);
            }
        }
        return true;
    }

    /**
     * 锁定库存 还是解锁逻辑实现
     * @param lockStockTastTO
     */
    @Override
    public void lockOrderStock(LockStockTastTO lockStockTastTO) {
        /**
         * 思路：先判断有没有这个锁定库存的单子
         * 有：再判断这个单子对应的订单存不存在
         *      存在：看订单状态
         *           已取消：就要解锁
         *           其他都不用解锁
         *      不存在：必须解锁
         * 没有：不用解锁 自己有异常了说明
         */
        Long taskId = lockStockTastTO.getTaskId();
        StockTaskDetailto stockTaskDetailto = lockStockTastTO.getStockTaskDetailto();
       WareOrderTaskDetailEntity wareOrderTaskDetailEntity=wareOrderTaskDetailService.hasTaskDetail(stockTaskDetailto);
        if(wareOrderTaskDetailEntity!=null){
            WareOrderTaskEntity taskEntity = wareOrderTaskService.getById(taskId);
            R status = orderFeignService.getOrderStatusByOrdersn(taskEntity.getOrderSn());
            if(status.getCode()==0){
                Ordervo data = status.getData("data", new TypeReference<Ordervo>() {
                });
                if(data==null||data.getStatus()==4){
                    if(wareOrderTaskDetailEntity.getLockStatus()==1){
                        //订单不存在或状态为关闭都要解锁
                        this.unLockStock(stockTaskDetailto.getSkuId(),stockTaskDetailto.getWareId(),stockTaskDetailto.getSkuNum());
                        WareOrderTaskDetailEntity wareOrderTaskDetailEntity1 = new WareOrderTaskDetailEntity();
                        wareOrderTaskDetailEntity1.setId(wareOrderTaskDetailEntity.getId());
                        wareOrderTaskDetailEntity1.setLockStatus(2);
                        wareOrderTaskDetailService.updateById(wareOrderTaskDetailEntity1);
                    }
                }else {
                    throw new RuntimeException("订单是正常的不要解锁");
                }
            }else {
                throw new RuntimeException("远程调用失败");
            }
        }else {

       }
    }

    /**
     * 解锁库存操作
     * @param
     */
    @Override
    public void unLockStock(Long skuId,Long wareId,Integer num) {
        WareSkuDao wareSkuDao = this.getBaseMapper();
        wareSkuDao.unLockStock(skuId,wareId,num);

    }

    /**
     * 关单 解锁库存
     * @param orderto
     */
    @Transactional
    @Override
    public void closeOrder(Orderto orderto) {
        //通过订单号找到工作单
        String orderSn = orderto.getOrderSn();
        WareOrderTaskEntity one = wareOrderTaskService.getOne(new LambdaQueryWrapper<WareOrderTaskEntity>().eq(WareOrderTaskEntity::getOrderSn, orderSn));

        List<WareOrderTaskDetailEntity> wareOrderTaskDetailEntities = wareOrderTaskDetailService.list(new LambdaQueryWrapper<WareOrderTaskDetailEntity>()
                .eq(WareOrderTaskDetailEntity::getTaskId, one.getId())
                .eq(WareOrderTaskDetailEntity::getLockStatus, 1));
        for (WareOrderTaskDetailEntity detailEntity : wareOrderTaskDetailEntities) {
            if(detailEntity!=null){
                unLockStock(detailEntity.getSkuId(),detailEntity.getWareId(),detailEntity.getSkuNum());
            }
        }
    }

    //sku对应仓库的类
    @Data
    class HasStockSkuWare{
        private Long skuId;
        private Integer num;
        private List<Long> wareIds;
    }

}